// Magic Software, Inc.
// http://www.magic-software.com
// Copyright (c) 2000, All Rights Reserved
//
// Source code from Magic Software is supplied under the terms of a license
// agreement and may not be copied or disclosed except in accordance with the
// terms of that agreement.  The various license agreements may be found at
// the Magic Software web site.  This file is subject to the license
//
// RESTRICTED USE SOURCE CODE
// http://www.magic-software.com/License/restricted.pdf

#include "MgcOglRenderer.h"

GLenum MgcOglRenderer::ms_aeTextureCorrection[MgcTexture::CM_QUANTITY] =
{
    GL_FASTEST,
    GL_NICEST
};

GLenum MgcOglRenderer::ms_aeTextureApply[MgcTexture::AM_QUANTITY] =
{
    GL_REPLACE,
    GL_DECAL,
    GL_MODULATE,
    GL_BLEND
};

GLenum MgcOglRenderer::ms_aeTextureFilter[MgcTexture::FM_QUANTITY] =
{
    GL_NEAREST,
    GL_LINEAR
};

GLenum MgcOglRenderer::ms_aeTextureMipmap[MgcTexture::MM_QUANTITY] =
{
    GL_NEAREST,  // MM_NONE (no mipmap)
    GL_NEAREST,
    GL_LINEAR,
    GL_NEAREST_MIPMAP_NEAREST,
    GL_NEAREST_MIPMAP_LINEAR,
    GL_LINEAR_MIPMAP_NEAREST,
    GL_LINEAR_MIPMAP_LINEAR
};

GLenum MgcOglRenderer::ms_aeImageComponents[MgcImage::IT_QUANTITY] =
{
    GL_RGBA4,
    GL_RGB8,
    GL_RGB5_A1,
    GL_RGBA8
};

GLenum MgcOglRenderer::ms_aeImageFormats[MgcImage::IT_QUANTITY] =
{
    GL_RGBA,
    GL_RGB,
    GL_RGBA,
    GL_RGBA
};

//----------------------------------------------------------------------------
void MgcOglRenderer::SetTextureState (MgcTextureState* pkState)
{
    unsigned int uiQuantity = pkState->GetQuantity();
    if ( uiQuantity > 0 )
    {
        glEnable(GL_TEXTURE_2D);

        for (unsigned int uiI = 0; uiI < MgcTextureState::MAX_TEXTURES; uiI++)
        {
            MgcTexture* pkTexture = pkState->Get(uiI);
            if ( !pkTexture )
                continue;

            if ( pkTexture->UserData() == 0 )
            {
                // texture seen first time, generate name and create data
                glGenTextures(1,&pkTexture->UserData());

                // bind the texture
                glBindTexture(GL_TEXTURE_2D,pkTexture->UserData());

                // pass image data to OpenGL
                MgcImage* pkImage = pkTexture->GetImage();
                if ( pkTexture->Mipmap() == MgcTexture::MM_NONE )
                {
                    glTexImage2D(GL_TEXTURE_2D,0,
                        ms_aeImageComponents[pkImage->GetType()],
                        pkImage->GetWidth(),pkImage->GetHeight(),0,
                        ms_aeImageFormats[pkImage->GetType()],
                        GL_UNSIGNED_BYTE,pkImage->GetData());
                }
                else
                {
                    gluBuild2DMipmaps(GL_TEXTURE_2D,
                        ms_aeImageComponents[pkImage->GetType()],
                        pkImage->GetWidth(),pkImage->GetHeight(),
                        ms_aeImageFormats[pkImage->GetType()],
                        GL_UNSIGNED_BYTE,pkImage->GetData());
                }
            }
            else
            {
                // texture already exists in OpenGL, just bind it
                glBindTexture(GL_TEXTURE_2D,pkTexture->UserData());
            }

            // set up correction mode
            glHint(GL_PERSPECTIVE_CORRECTION_HINT,
                ms_aeTextureCorrection[pkTexture->Correction()]);

            // set up apply mode
            glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,
                ms_aeTextureApply[pkTexture->Apply()]);

            glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,
                (const GLfloat*)&pkTexture->BlendColor());

            // set up wrap mode
            switch ( pkTexture->Wrap() )
            {
            case MgcTexture::WM_CLAMP_S_CLAMP_T:
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,
                    GL_CLAMP);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,
                    GL_CLAMP);
                break;
            case MgcTexture::WM_CLAMP_S_WRAP_T:
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,
                    GL_CLAMP);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,
                    GL_REPEAT);
                break;
            case MgcTexture::WM_WRAP_S_CLAMP_T:
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,
                    GL_REPEAT);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,
                    GL_CLAMP);
                break;
            case MgcTexture::WM_WRAP_S_WRAP_T:
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,
                    GL_REPEAT);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,
                    GL_REPEAT);
                break;
            }

            // set up filter mode
            glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,
                ms_aeTextureFilter[pkTexture->Filter()]);

            // set up mipmap mode
            glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,
                ms_aeTextureMipmap[pkTexture->Mipmap()]);
        }
    }
    else
    {
        glDisable(GL_TEXTURE_2D);
    }
}
//----------------------------------------------------------------------------
